package u1;

import static java.lang.System.*;
import static u1.Util.*;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;

import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

/**
 * Read in the AdjList produced by ForwardLinks and print it out as nice HTML,
 * for sanity checking. Takes two arguments, corresponding to those of
 * ForwardLinks. Writes HTML to standard out.
 * 
 * NB: JLM wrote this for small datasets. It's unlikely that it will work on the
 * big dataset, but we probably don't want to pretty print that anyway.
 */
public class PrettyAdjList {
  public static void main(String[] argv) throws XMLStreamException,
      FactoryConfigurationError, IOException {
    if (argv.length != 2) {
      err.println("Consult comments for usage.");
      exit(-1);
    }
    String adjFile = argv[0] + ForwardLinks.EXT_FORWARD;
    String redirectFile = argv[0] + ForwardLinks.EXT_REDIRECT;
    String titlesFile = argv[1];

    /*
     * Read titles first. The assigned ordinals correspond to the order of the
     * titles in the titles file. We also need the reverse map (which we could
     * get much more efficiently, but oh well).
     */
    trace("Reading titles from %s...", titlesFile);
    BufferedReader titles = new BufferedReader(new InputStreamReader(
        new FileInputStream(new File(titlesFile)), "UTF-8"));
    Map<String, Integer> ordinals = readStringIndex(titles);
    titles.close();
    trace("Read %d titles.", ordinals.size());

    Map<Integer, String> pages = new HashMap<Integer, String>();
    reverse(ordinals, pages);

    /*
     * Read the adjacency list (a multi map).
     */
    trace("Loading adj list %s...", adjFile);
    final Map<Integer, Set<Integer>> adj = new HashMap<Integer, Set<Integer>>(
        PAGES_MAX);
    AdjReader reader = new AdjReader() {

      @Override
      public void readLinks(Integer source, Collection<Integer> targets) {
        adj.put(source, new HashSet<Integer>(targets));
      }

    };
    reader.read(new File(adjFile));
    trace("Loaded adj list with %d pages.", adj.size());
    trace("Reader says it read %d pages and %d links.", reader.getPageIndex(),
        reader.getLinkCount());

    trace("Loading redirect info...");
    Set<Integer> redirects = new HashSet<Integer>();
    File redirect = new File(redirectFile);
    if (redirect.exists()) {
      Scanner s = null;
      try {
        s = new Scanner(redirect, "UTF-8");
        while (s.hasNextInt()) {
          redirects.add(s.nextInt());
        }
      } finally {
        if (s != null)
          s.close();
      }
    }
    trace("Loaded %d redirections.", redirects.size());

    XMLStreamWriter writer = XMLOutputFactory.newInstance()
        .createXMLStreamWriter(out);
    writer.writeStartDocument("UTF-8", "1.0");
    writer.writeStartElement("html");
    writer.writeStartElement("head");
    writer.writeStartElement("title");
    writer.writeCharacters(String.format("%s pretty print", argv[0]));
    writer.writeEndElement();
    writer.writeEndElement();
    writer.writeStartElement("body");
    writer.writeStartElement("dl");
    for (Map.Entry<Integer, Set<Integer>> e : adj.entrySet()) {
      writer.writeStartElement("dt");
      writer.writeStartElement("a");
      writer.writeAttribute("name", e.getKey().toString());
      writer.writeEndElement();
      writer.writeCharacters(pages.get(e.getKey()));
      if (redirects.contains(e.getKey()))
        writer.writeCharacters("*");
      writer.writeEndElement();
      writer.writeStartElement("dd");
      for (Integer i : e.getValue()) {
        writer.writeStartElement("a");
        writer.writeAttribute("href", "#" + i.toString());
        writer.writeCharacters(pages.get(i));
        writer.writeEndElement();
        writer.writeCharacters(" ");
      }
      writer.writeEndElement();
    }
    writer.writeEndDocument(); // closes any open tags
    writer.close();
  }
}
/*
* Copyright (c) 2009 John Lees-Miller
* 
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
* 
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

